﻿/**
 * 		  应用程序FPS与内存监视器
 * @author sailor
 * @modify 2009-3-25
 * @url http://readkid.cn
 */
package com.bardpub.controls {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.system.System;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.getTimer;
	
	public class FpsMonitor extends Sprite {
		
		private var _fpsField:TextField;							//显示实时FPS的文本
		private var _memoryField:TextField;							//显示实时内存的文本
		
		
		private var _tfDelay:int = 0;								//记时器数字
		private var _tfTimer:int;									//fps记时器时间
		private var ramTimer:int;									//内存记时器时间
		private var ram:BitmapData;
		
		private static var _instance:FpsMonitor;					//单例 FpsMonitor 对象
		private static const TFDELAYLIMIT:int = 10;					//更新显示的帧数
		private static const RAMWIDTH:int = 62;					    //监视器的宽度
		private static const RAMHEIGHT:int = 40;
		private static const MEMORYLIMIT:uint = 4.1943e+007;		//定义最大内存
		
		/**
		 * 创建	cn.readkid.display.FpsMonitor 类的新实例
		 */
		public function FpsMonitor(instance:Instance) {
			_instance = this;
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		//初始化监视器
		private function init(event:Event):void {
			
			_fpsField = new TextField();
			_memoryField = new TextField();
			
			mouseEnabled = false;
			mouseChildren = false;
				
			var format:TextFormat = new TextFormat("Tahoma", 10, 13421772);
			_fpsField.selectable = _memoryField.selectable = false;
				
			//设置FPS TextField
			_fpsField.defaultTextFormat = format;
			_fpsField.autoSize = "left";
			_fpsField.text = "FPS: " + Number(stage.frameRate).toFixed(2);
			_fpsField.x = -RAMWIDTH - 2;
			addChild(_fpsField);
				
			//设置Memory TextField
			format.color = 4278255360;
			_memoryField.defaultTextFormat = format;
			_memoryField.autoSize = "left";
			_memoryField.text = "MEM: " + bytesToString(System.totalMemory);
			_memoryField.x = -RAMWIDTH - 2;
			_memoryField.y = 10;
			addChild(_memoryField);
			
			ram = new BitmapData(RAMWIDTH, RAMHEIGHT, true, 553648127);
			var bit:Bitmap = new Bitmap(ram);
			addChild(bit);
			bit.x = -RAMWIDTH;
			bit.y = 24;
				
			_tfTimer = getTimer();
			ramTimer = _tfTimer;
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			stage.addEventListener(Event.RESIZE, onResize);
			onResize();
		}
		
		
		private function enterFrameHandler(event:Event):void {
			
			//取FPS
			_tfDelay++;
			if (_tfDelay >= TFDELAYLIMIT) {
				_tfDelay = 0;
				var currentTime = getTimer();
				_fpsField.text = "FPS: " + Number(1000 * TFDELAYLIMIT / (currentTime - _tfTimer)).toFixed(2);
				_tfTimer = currentTime;
			}
			
			//取内存
			_memoryField.text = "MEM: " + bytesToString(System.totalMemory);
			
			ram.scroll(1, 0);
			var tmp:Number = 1000 / (getTimer() - ramTimer);
            var currentc:Number = tmp > stage.frameRate ? (1) : (tmp / stage.frameRate);
            ramTimer = getTimer();
            ram.fillRect(new Rectangle(0, 0, 1, ram.height), 553648127);
            ram.setPixel32(0, RAMHEIGHT * (1 - currentc), 4291611852);
			var maxc:Number = System.totalMemory / MEMORYLIMIT;
            ram.setPixel32(0, RAMHEIGHT * (1 - maxc), 4278255360);
		
		}
		
		
		public function register(container:DisplayObjectContainer):void 
		{
			if (this.parent) return;
			if (container.stage)
			{
				container.stage.addChild(_instance);
			}
			else 
			{
				container.addEventListener(Event.ADDED_TO_STAGE, onContainerAddedToStage);
			}
		}
		
		private function onContainerAddedToStage(e:Event):void 
		{
			e.target.removeEventListener(Event.ADDED_TO_STAGE, onContainerAddedToStage);
			DisplayObjectContainer(e.currentTarget).stage.addChild(_instance);
			
		}
		
		
/*=======================静态函数===============================*/

		/**
		 * FpsMonitor静态入口
		 * @return 唯一的 FpsMonitor 实例
		 */
		public static function getInstance():FpsMonitor {
			if (_instance == null) {
				_instance = new FpsMonitor(new Instance());
			}
			return _instance;
		}
		
		

/*=======================功能函数===============================*/

		//自适应屏幕
		private function onResize(param1:Event = null) : void {
			
            var tmp:Point = (parent == root) ? new Point(stage.stageWidth, 0) : parent.globalToLocal(new Point(stage.stageWidth, 0));
            x = tmp.x;
            y = tmp.y;
            return;
        }
		
		//转换byte数值为显示文本
		private function bytesToString(byte:uint) : String {
            var result:String;
            if (byte < 1024) {
                result = String(byte) + "Byte";
            } else if (byte < 10240) {
                result = Number(byte / 1024).toFixed(2) + "KB";
            } else if (byte < 102400) {
                result = Number(byte / 1024).toFixed(1) + "KB";
            } else if (byte < 1048576) {
                result = Math.round(byte / 1024) + "KB";
            } else if (byte < 10485760) {
                result = Number(byte / 1048576).toFixed(2) + "MB";
            } else if (byte < 104857600) {
                result = Number(byte / 1048576).toFixed(1) + "MB";
            } else {
                result = Math.round(byte / 1048576) + "MB";
            }
            return result;
        }
		
		
	}
}
class Instance {
	
}